package com.snail.common.dyd.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.snail.common.dyd.DataSourceIdProvider;
import com.snail.common.dyd.DynamicDataBase;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;

import java.lang.reflect.Method;

@Data
@Slf4j
public class DataSourceIdFromAspectProvider implements DataSourceIdProvider {

    private ProceedingJoinPoint proceedingJoinPoint;

    private final DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

    public DataSourceIdFromAspectProvider(ProceedingJoinPoint proceedingJoinPoint) {
        this.proceedingJoinPoint = proceedingJoinPoint;
    }
    @Override
    public String getDataSourceId() {
        Object target = getProceedingJoinPoint().getTarget();
        if(!(target instanceof DynamicDataBase)){
            log.error("指定的对象不是DynamicDataBase，不自动切换数据源");
            return "";
        }
        Object[] args = getProceedingJoinPoint().getArgs();
        String dataSourceIdFileName = ((DynamicDataBase)target).getDataSourceIdVariableName();
        if(StrUtil.isBlank(dataSourceIdFileName)){
            log.error("指定的数据源变量名称为空，不自动切换数据源");
            return "";
        }
        // 2.从方法参数中获取到数据源的代号
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        // 获取方法参数名
        String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
        int dataSourceCodeArgIndex = parameterNames == null?-1: ArrayUtil.indexOf(parameterNames, dataSourceIdFileName);
        if(dataSourceCodeArgIndex<0){
            log.error("指定的数据源变量名称{}在方法参数中不存在，不自动切换数据源",dataSourceIdFileName);
            return "";
        }
        String dataSourceId = (String) args[dataSourceCodeArgIndex];
        if(StrUtil.isBlank(dataSourceId)){
            log.error("指定的数据源变量值为空，不自动切换数据源");
            return "";
        }
        return dataSourceId;
    }
}
